package com.fuyin.commons.aspect;

import com.fuyin.commons.utils.JwtTokenUtil;
import com.fuyin.commons.utils.MyUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

/**
 * @author yuanxilan (yuanxilan@keep.com)
 * @Description
 * @date 2021年12月17日 1:45 AM
 * @since
 */
@Aspect
@Component
@Slf4j
public class RequestLogAspect {

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 设置操作日志切入点   在注解的位置切入代码
     */
    @Pointcut("@annotation(com.fuyin.commons.aop.RequestLogAnnotation)")
    public void operLogPoinCut() {
    }

    @Before(value = "operLogPoinCut()")
    public void saveQuestionLog2(JoinPoint joinPoint) throws Throwable {
        // 获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        if (Objects.isNull(request)) {
            log.error("com.fuyin.commons.aspect.OperationLogAspect.saveOperLog request is null");
            return;
        }
        String userName = request.getHeader("userName");
        if (StringUtils.isBlank(userName)) {
            String token = request.getHeader("Authorization");
            token = StringUtils.substring(token, tokenHead.length());
            userName = jwtTokenUtil.getUserNameFromToken(token);
        }
        log.info("{} userName: {}, method: {}, args: {}, ip: {}", Timestamp.valueOf(sdf.format(new Date())),
                userName, joinPoint.getSignature().getName(), Arrays.asList(joinPoint.getArgs()),
                MyUtils.getIpAddr(request));
    }

    @AfterReturning(returning  /**
     * 记录操作日志
     * @param joinPoint 方法的执行点
     * @param result  方法返回值
     * @throws Throwable
     */ = "result", value = "operLogPoinCut()")
//    @Before(value = "operLogPoinCut()")
    public void saveQuestionLog(JoinPoint joinPoint, Object result) throws Throwable {
        // 获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        if (Objects.isNull(request)) {
            log.error("com.fuyin.commons.aspect.OperationLogAspect.saveOperLog request is null");
            return;
        }
        String userName = request.getHeader("userName");
        if (StringUtils.isBlank(userName)) {
            String token = request.getHeader("Authorization");
            token = StringUtils.substring(token, tokenHead.length());
            userName = jwtTokenUtil.getUserNameFromToken(token);
        }
        log.info("{} userName: {}, method: {}, args: {}, ip: {}, result: {}", Timestamp.valueOf(sdf.format(new Date())),
                userName, joinPoint.getSignature().getName(), Arrays.asList(joinPoint.getArgs()),
                MyUtils.getIpAddr(request), result);
    }
}
